package com.vaha.application.service.impl;


import com.cyber.domain.constant.HttpResultCode;
import com.cyber.domain.exception.BusinessException;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.vaha.application.service.PasswordService;
import com.vaha.domain.entity.UserAccount;
import com.vaha.infrastructure.toolkit.PasswordUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

@Service
@RequiredArgsConstructor
public class PasswordServiceImpl implements PasswordService {

//    private final LoginInforService loginInforService;
//
//    private final LoginExceptionService loginExceptionService;


    private static LoadingCache<String, Integer> localCache =
            CacheBuilder.newBuilder().initialCapacity(1000).maximumSize(10000).expireAfterAccess(5, TimeUnit.MINUTES)
                    //build里面要实现一个匿名抽象类
                    .build(new CacheLoader<String, Integer>() {
                        @Override
                        public Integer load(String key) {
                            return 0;
                        }
                    });

    private static final int MAX_RETRY_COUNT = 5;

    private static final Long LOCK_TIME = 10L;

    private static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:";

    @Override
    public void validate(UserAccount userAccount, String password) {
        String account = userAccount.getAccount();

        Integer retryCount = getKey(getCacheKey(account));

        if (retryCount == null) {
            retryCount = 0;
        }

        if (retryCount >= MAX_RETRY_COUNT) {
            String errMsg = String.format("密码输入错误%s次，帐户锁定%s分钟", MAX_RETRY_COUNT, LOCK_TIME);
//            loginInforService.insertLoginInfor(user.getId(), username, UserConstants.LOGIN_FAIL, errMsg);
//            loginExceptionService.save(user.getId(), username, UserConstants.LOGIN_FAIL, errMsg);
            throw new BusinessException(errMsg, HttpResultCode.VALIDATE_ERROR.getCode());
        }

        if (!matches(userAccount, PasswordUtil.encrypt(userAccount.getAccount(), password, userAccount.getSalt()))) {
            retryCount = retryCount + 1;
//            loginInforService.insertLoginInfor(user.getId(), username, UserConstants.LOGIN_FAIL, String.format("密码输入错误%s次", retryCount));
//            loginExceptionService.save(user.getId(), username, UserConstants.LOGIN_FAIL, String.format("密码输入错误%s次", retryCount));
            setKey(getCacheKey(account), retryCount);
            throw new BusinessException("用户不存在/密码错误", HttpResultCode.VALIDATE_ERROR.getCode());
        } else {
            clearLoginRecordCache(account);
        }
    }

    /**
     * 登录账户密码错误次数缓存键名
     *
     * @param username 用户名
     * @return 缓存键key
     */
    private String getCacheKey(String username) {
        return PWD_ERR_CNT_KEY + username;
    }

    private boolean matches(UserAccount userAccount, String rawPassword) {
        return rawPassword.equals(userAccount.getPassword());
    }

    private void clearLoginRecordCache(String loginName) {
        setKey((getCacheKey(loginName)), 0);
    }


    /*
     * 添加本地缓存
     * */
    public static void setKey(String key, Integer value) {
        localCache.put(key, value);
    }

    /*
     * 得到本地缓存
     * */
    public static Integer getKey(String key) {
        try {
            return localCache.get(key);
        } catch (ExecutionException e) {
            return 0;
        }
    }
}
